---
id: async
title: createDraft / finishDraft
sidebar_label: createDraft / finishDraft
---

<center>
	<div
		data-ea-publisher="immerjs"
		data-ea-type="image"
		className="horizontal bordered"
	></div>
</center> <details>
	<summary className="egghead-summary">
		egghead.io 第11课: 创建<b>异步</b> producers（以及为什么不应该这样做）
	</summary>
	<br />
	<div>
		<iframe
			width="760"
			height="427"
			scrolling="no"
			src="https://egghead.io/lessons/react-write-asynchronous-producers-in-immer-and-why-you-shouldn-t/embed"
		></iframe>
	</div>
	<a
		className="egghead-link"
		href="https://egghead.io/lessons/react-write-asynchronous-producers-in-immer-and-why-you-shouldn-t"
	>
		Hosted on egghead.io
	</a>
</details>

## `createDraft` and `finishDraft`

`createDraft` 和 `finishDraft` 是两个底层函数，它们对于在 immer 之上构建抽象的库非常有用。它避免了为了使用 draft 始终创建函数。相反，人们可以创建一个 draft，对其进行修改，并在未来的某个时间完成该 draft，在这种情况下，将产生下一个不可变状态。例如，我们可以将上面的示例重写为：

Beyond that, `createDraft` / `finishDraft` could be used to express async updates to drafts:

```javascript
import {createDraft, finishDraft} from "immer"

const user = {
	name: "michel",
	todos: []
}

const draft = createDraft(user)
draft.todos = await (await window.fetch("http://host/" + draft.name)).json()
const loadedUser = finishDraft(draft)
```

注意：`finishDraft` 以一个 `patchListener` 作为第二个参数，可以用来记录 patches，类似于 `produce`

_警告：一般情况下，我们建议使用 `producer` 而不是 `createDraft / finishDraft` 组合，`produce` 在使用中不易出错，并且在代码中更清楚地区分了可变性和不变性的概念。_
